package com.borball.store.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.borball.store.util.SessionFactory;

public abstract class AbstractDAO<T> implements DAO<T> {

	protected Class<T> clazz;

	@SuppressWarnings("unchecked")
	public AbstractDAO() {
		this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public T findByPK(Object o) {
		return findOne(clazz.getName() + ".findByPK", o);
	}

	@SuppressWarnings("unchecked")
	private T findOne(String sqlId, Object o) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			return (T) session.selectOne(sqlId, o);
		} finally {
			session.close();
		}
	}

	public T findByUnique(Object o) {
		return findOne(clazz.getName() + ".findByUnique", o);
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			return (List<T>) session.selectList(clazz.getName() + ".findAll");
		} finally {
			session.close();
		}
	}

	public void add(T t) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			session.insert(clazz.getName() + ".add", t);
		} finally {
			session.commit(true);
			session.close();
		}
	}
	
	public void update(T t) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			session.update(clazz.getName() + ".update", t);
		} finally {
			session.commit(true);
			session.close();
		}
	}

	public void delete(T t) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			session.delete(clazz.getName() + ".delete", t);
		} finally {
			session.commit(true);
			session.close();
		}

	}

	public void deleteByUnique(Object o) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			session.delete(clazz.getName() + ".deleteByUnique", o);
		} finally {
			session.commit(true);
			session.close();
		}

	}

	public void deleteByPK(Object o) {
		SqlSession session = SessionFactory.getInstance().getSqlSessionFactory().openSession();

		try {
			session.delete(clazz.getName() + ".deleteByPK", o);
		} finally {
			session.commit(true);
			session.close();
		}
	}

}
